/*
 * ConnManager.java
 *
 * Created on June 10, 2002, 2:24 PM
 */

package com.xtera.nuwave.tools.redundancy.redman;

import java.lang.*;
import java.util.*;
import java.io.*;
import java.net.*;
import javax.net.*;
import javax.net.ssl.*;
import com.sun.net.ssl.*;
import java.rmi.server.*;
import java.security.KeyStore;
import javax.security.cert.X509Certificate;
import org.apache.log4j.*;
import java.security.*;



/**
 *
 * @author  llaranje
 * @version 
 */
public class ConnManager {
    
    private static Category trace = Category.getInstance(ConnManager.class);

    /** Creates new ConnManager */
    public ConnManager() throws IOException {
        // ServerSocket svso = null;
        //SSLServerSocket svso = null;
        try {
            trace.debug("Connection Manager running ...");
            
            // Wait for connection and create a thread to handle it
            for(;;) {
                //Socket clso = svso.accept();
                SSLSocket clso = (SSLSocket)RedMan.svso.accept();
                clso.setTcpNoDelay(true);
                trace.info("RedMan got a connection");
                
                HandleClientThread clt = new HandleClientThread(clso);
                clt.start();
            }
        }
        catch (Exception e) {
            trace.error("Exception: " + e.getMessage());
        }
    }
    
    public static String authenticate (String msg) {
        StringTokenizer st = new StringTokenizer(msg);
        String user, encPass, passwd;
        
        if (st.countTokens() != 2) return("NACK INVALID_LOGIN_INFO");
        
        user = st.nextToken();
        // trace.info("user = " + user);
        if (!user.equals("REDMAN") && !user.equals("OPINT") && !isAppName(user)) {
            trace.error("User '" + user + "' not recognized - Failing authentication");
            return ("NACK INVALID_USER");
        }
        // trace.info("user '" + user + "' authenticated");
        encPass = st.nextToken();
        // trace.info("received encrypted passwd = " + encPass);
        if (verify(encPass)) return("ACK");
        else {
            trace.error("Password (encrypted) '" + encPass + "' not recognized - Failing authentication");
            return ("NACK INVALID_PASSWD");
        }
    }
    
    private static boolean verify(String encPasswd) {
            String truePasswd = "resu@#$nam&*^der";
            String encryptedPass = unidirectionalEncryption(truePasswd);

            if(encPasswd.equals(encryptedPass)) {
                // trace.info("received encrypted passwd EQUAL to expected encrypted passwd");
                return true;
            }
            else {
                trace.error("received encrypted passwd (" + encPasswd + ") is DIFFERENT from expected "
                                    + "encrypted passwd (" + encryptedPass + ")");
                return false;
            }
    }
        
    public static String unidirectionalEncryption(String password)
    {
        String encryptedPass = null;
        try
        {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.reset();
            byte[] bytes = password.getBytes();
            encryptedPass = convertToString(md.digest(bytes));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
        return encryptedPass;

    } //end of method unidirectionalEncryption

    private static String convertToString(byte[] bytes)
    {

        StringBuffer hexString = new StringBuffer();
        int noOfBytes = bytes.length;
        for (int i = 0; i < noOfBytes; i++)
        {
            String digit = Integer.toHexString(0xFF & bytes[i]);
            if (digit.length() == 1)
            {
                digit = "0" + digit;
            }
            hexString.append(digit);
        }
        //System.out.println(hexString.toString());
        return hexString.toString();

    } //end of method convertToString
    
    private static boolean isAppName(String appname) {
        boolean retval = false;
        // Find if appname is a defined application name
        for (int i = 0; i < RedMan.appnum; i++) {
            if (RedMan.appmons[i].name.equals(appname)) retval = true;
        }    
        return(retval);
    }
}
